#ifndef __PROTOBUFFIK_ARRAY_H_
#define __PROTOBUFFIK_ARRAY_H_

#include <vector>
#include "protobuffik_types.h"
#include "protobuffik_stream.h"
#include "protobuffik_results.h"
#include "protobuffik_save_load.h"


namespace protobuffik
{

template< typename ValueType, uint_32 MaxSize = 0xFFFFFFFF >
class fixed_array : public std::vector< ValueType >
{
public:
	fixed_array( )
	{
	}

	size_t save( ostream& out ) const
	{
		size_t bytesSaved = 0;

		uint_32 n = std::vector< ValueType >::size( );
		if( n > MaxSize )
			n = MaxSize;

		bytesSaved += save_count< MaxSize >( out, n );

		for( uint_32 i = 0; i < n; ++i )
			bytesSaved += protobuffik::save( out, std::vector< ValueType >::operator[]( i ) );

		return bytesSaved;
	}

	LoadingResult load( istream& in, size_t& bytesLoaded )
	{
		std::vector< ValueType >::clear( );

		bytesLoaded = 0;

		uint_32 n = 0;

		size_t b = 0;
		LoadingResult r = load_count< MaxSize >( in, n, b );
		if( r != LOADING_RESULT_OK )
			return r;

		bytesLoaded = b;

		if( n > MaxSize )
			n = MaxSize;

		for( uint_32 i = 0; i < n; ++i )
		{
			std::vector< ValueType >::push_back( ValueType( ) );
			ValueType& l = std::vector< ValueType >::back( );

			b = 0;
			r = protobuffik::load( in, l, b );

			if( r != LOADING_RESULT_OK )
			{
				std::vector< ValueType >::pop_back( );

				return r;
			}

			bytesLoaded += b;
		}

		return LOADING_RESULT_OK;
	}

	LoadingResult load( istream& in )
	{
		size_t bytesLoaded = 0;
		return load( in, bytesLoaded );
	}
};

};

#endif